package com.geovis.emergency.spd.biz.pc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geovis.common.auth.util.AuthUtil;
import com.geovis.common.core.exception.BizException;
import com.geovis.common.mybatis.page.PageParam;
import com.geovis.common.mybatis.page.PageResult;
import com.geovis.emergency.spd.biz.command.service.IOdsZgtfwTyphoonService;
import com.geovis.emergency.spd.biz.command.service.TfService;
import com.geovis.emergency.spd.biz.custom.service.ITyphoonService;
import com.geovis.emergency.spd.biz.iflytek.thread.PushThread;
import com.geovis.emergency.spd.biz.pc.mapper.*;
import com.geovis.emergency.spd.biz.pc.service.*;
import com.geovis.emergency.spd.biz.system.mapper.SystemUserRoleMapper;
import com.geovis.emergency.spd.biz.system.service.ISystemFileBusinessService;
import com.geovis.emergency.spd.biz.system.service.ISystemFileService;
import com.geovis.emergency.spd.biz.system.service.ISystemUserRoleService;
import com.geovis.emergency.spd.biz.system.service.ISystemUserService;
import com.geovis.emergency.spd.entity.command.pojo.vo.OdsTyphoonVO;
import com.geovis.emergency.spd.entity.pc.entity.*;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcDrillConstant;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcMessageConstant;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillQueryDTO;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillSaveDTO;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillUpdateDTO;
import com.geovis.emergency.spd.entity.pc.pojo.enums.*;
import com.geovis.emergency.spd.entity.pc.pojo.vo.DrillStatisticsVO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.PcDrillDutyOrgVO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.PcDrillVO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.PcSchedulingEventVO;
import com.geovis.emergency.spd.entity.system.constant.SystemFileBusinessConstant;
import com.geovis.emergency.spd.entity.system.constant.SystemRoleConstant;
import com.geovis.emergency.spd.entity.system.entity.SystemFile;
import com.geovis.emergency.spd.entity.system.entity.SystemFileBusiness;
import com.geovis.emergency.spd.entity.system.entity.SystemUser;
import com.geovis.emergency.spd.entity.system.entity.SystemUserRole;
import com.geovis.emergency.spd.entity.system.pojo.dto.SystemFileDTO;
import com.geovis.emergency.spd.entity.system.pojo.dto.SystemFileQueryDTO;
import com.geovis.emergency.spd.entity.system.pojo.enums.RoleTypeEnum;
import com.geovis.emergency.spd.util.MsgUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hsqldb.lib.Collection;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 应急预案指挥模块-演练表 服务实现类
 * </p>
 */

@Service
@RequiredArgsConstructor
@Slf4j
public class PcDrillServiceImpl extends ServiceImpl<PcDrillMapper, PcDrill> implements IPcDrillService {

    private final IPcDutyService pcDutyService;
    private final IPcDrillDisasterService pcDrillDisasterService;
    private final IPcDrillDisasterEventService pcDrillDisasterEventService;
    private final ISystemFileBusinessService systemFileBusinessService;
    private final ISystemFileService systemFileService;
    private final ITyphoonService typhoonService;
    private final IOdsZgtfwTyphoonService odsZgtfwTyphoonService;
    private final PcDrillDisasterEventMapper pcDrillDisasterEventMapper;
    private final PcDrillDutyUserMapper pcDrillDutyUserMapper;
    private final PcDrillDutyOrgMapper pcDrillDutyOrgMapper;
    private final SystemUserRoleMapper systemUserRoleMapper;
    private final IPcDrillDutyOrgService pcDrillDutyOrgService;

    private final PcSchedulingEventMapper schedulingEventManager;
    private final IPcSchedulingEventService schedulingEventService;
    private final PcDrillUserRoleMapper pcDrillRoleUserMapper;
    private final ISystemUserRoleService systemUserRoleService;
    private final IPcDisasterService pcDisasterService;

    private final ISystemUserService systemUserService;

    private final IPcDrillPlanDetailService pcDrillPlanDetailService;

    private final IPcDrillPlanTaskService pcDrillPlanTaskService;

    private final TfService tfService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePcDrill(PcDrillSaveDTO saveDTO) {
        // 新增演练
        PcDrill entity = BeanUtil.toBean(saveDTO, PcDrill.class);
        entity.setStatus(PcDrillConstant.STATUS_PREPARE);
        if (StrUtil.isBlank(saveDTO.getDrillType())){
            entity.setDrillType(DrillTypeEnum.PLANNING_DRILL.getCode());
        }
        save(entity);
        // 处理附件
        if (CollUtil.isNotEmpty(saveDTO.getFileIdList())) {
            Set<SystemFileBusiness> fileBusinessSet = CollUtil.set(false);
            saveDTO.getFileIdList().forEach(fileId ->
                    fileBusinessSet.add(new SystemFileBusiness(fileId, SystemFileBusinessConstant.TYPE_PC_DRILL, entity.getId())));
            systemFileBusinessService.saveBatch(fileBusinessSet);
        }
        //将演练关联到主事件
        if (DrillTypeEnum.EMERGENCY_COMMAND.getCode().equals(saveDTO.getDrillType()) && StrUtil.isNotBlank(saveDTO.getEventId())){
            schedulingEventManager.update(null,
                    Wrappers.lambdaUpdate(PcSchedulingEvent.class)
                            .eq(PcSchedulingEvent::getId,saveDTO.getEventId())
                            .set(PcSchedulingEvent::getDrillId,entity.getId())
                            .set(PcSchedulingEvent::getStatus,EventStatusEnum.WAIT_START.getCode())
            );
        }
//        MsgUtil.saveMsg(PcMessageConstant.TYPE_DRILL_ADD,"创建演练","应急演练【已创建】",entity.getId(),entity.getId());
//        MsgUtil.pushMsgByUser(PcMessageConstant.TYPE_DRILL_ADD,"创建演练","应急演练【已创建】",entity.getId(),entity.getId(),AuthUtil.getCurrUser().getUserId());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePcDrill(PcDrillUpdateDTO updateDTO){
        PcDrill pcDrill = baseMapper.selectById(updateDTO.getId());
        Assert.notNull(pcDrill,"演练不存在");
        BeanUtil.copyProperties(updateDTO, pcDrill);
        baseMapper.updateById(pcDrill);
        if (ObjectUtil.isNotEmpty(updateDTO.getFileIdList())){
            //删除演练中已经删除的附件
            systemFileBusinessService.remove(Wrappers.<SystemFileBusiness>lambdaQuery()
                    .eq(SystemFileBusiness::getRelatedId,updateDTO.getId())
                    .eq(SystemFileBusiness::getType,SystemFileBusinessConstant.TYPE_PC_DRILL)
                    .notIn(SystemFileBusiness::getFileId,updateDTO.getFileIdList())
            );
        }
        if (CollUtil.isNotEmpty(updateDTO.getFileIdList())) {
            Set<SystemFileBusiness> fileBusinessSet = CollUtil.set(false);
            updateDTO.getFileIdList().forEach(fileId -> {
                //添加新增的附件
                if(systemFileBusinessService.count(Wrappers.<SystemFileBusiness>lambdaQuery()
                                .eq(SystemFileBusiness::getRelatedId,updateDTO.getId())
                                .eq(SystemFileBusiness::getType,SystemFileBusinessConstant.TYPE_PC_DRILL)
                                .eq(SystemFileBusiness::getFileId,fileId)) == 0){
                    fileBusinessSet.add(new SystemFileBusiness(fileId, SystemFileBusinessConstant.TYPE_PC_DRILL, updateDTO.getId()));
                }

                }
            );
            if (CollUtil.isNotEmpty(fileBusinessSet)) {
                systemFileBusinessService.saveBatch(fileBusinessSet);
            }
        }

//        Set<String> dutyUserIdList = MsgUtil.getDutyUserIdList(pcDrill.getId());
//        dutyUserIdList.add(AuthUtil.getCurrUser().getUserId());
//        for (String userId : dutyUserIdList) {
//            MsgUtil.pushMsgByUser(PcMessageConstant.TYPE_DRILL_UPDATE,"修改演练","应急演练【已修改】",pcDrill.getId(),pcDrill.getId(),userId);
//        }


    }

    @Override
    public PcDrillVO detailPcDrill(String drillId) {
        PcDrill pcDrill = baseMapper.selectById(drillId);
        Assert.notNull(pcDrill, "演练不存在");
        PcDrillVO pcDrillVO = new PcDrillVO();
        BeanUtil.copyProperties(pcDrill, pcDrillVO);

        //获取附件信息
        List<SystemFile> list = systemFileService.getListById(drillId,SystemFileBusinessConstant.TYPE_PC_DRILL);
        pcDrillVO.setFileList(list);

        //获取主事件
        PcDrillDisaster pcDrillDisaster = pcDrillDisasterService.getOne(
                Wrappers.lambdaQuery(PcDrillDisaster.class)
                        .eq(PcDrillDisaster::getEventType, EventTypeEnum.MAIN_EVENT.getCode())
                        .eq(PcDrillDisaster::getPcDrillId, drillId)
                        .last("limit 1")
        );
        //这里有可能还没有配置主事件
        if(pcDrillDisaster!=null)
        {
            //获取台风数据
            if (StringUtils.hasText(pcDrillDisaster.getTyphoonNo())){
                OdsTyphoonVO typhoon = tfService.getTyphoon(pcDrillDisaster.getTyphoonNo());
                pcDrillVO.setTyphoonNo(pcDrillDisaster.getTyphoonNo());
                pcDrillVO.setTyphoon(typhoon);
            }
        }
        return pcDrillVO;
    }

    @Override
    public PageResult listPage(PageParam<PcDrillQueryDTO> pageParam) {
        PcDrillQueryDTO queryDTO = pageParam.getQuery();
        IPage<PcDrill> page = pageParam.buildPage();
        LambdaQueryWrapper<PcDrill> wrapper=getWrapper(queryDTO);
        if(wrapper==null)
        {
            return new PageResult<>(null);
        }
        page(page, wrapper);
        if(CollectionUtils.isEmpty(page.getRecords()))
        {
            return new PageResult<>(null);
        }
        //设置用户的演练角色
        List<String> drillId=page.getRecords().stream().map(PcDrill::getId).collect(Collectors.toList());
        List<PcDrillUserRole> userRoles=pcDrillRoleUserMapper.selectList(Wrappers.lambdaQuery(PcDrillUserRole.class)
                .in(PcDrillUserRole::getPcDrillId,drillId)
                .eq(PcDrillUserRole::getUserId,AuthUtil.getCurrentUserId()));

        Map<String,String> drillRolesMap=userRoles.stream().collect(Collectors.toMap(PcDrillUserRole::getPcDrillId,PcDrillUserRole::getRoleName));
        IPage<PcDrillVO> drillVos= page.convert(data->{
            PcDrillVO pcDrillVO=new PcDrillVO();
            BeanUtils.copyProperties(data,pcDrillVO);
            pcDrillVO.setRole(drillRolesMap.get(data.getId()));
            //获取台风编号
            PcDrillDisaster disaster=pcDrillDisasterService.getOne(Wrappers.lambdaQuery(PcDrillDisaster.class).eq(PcDrillDisaster::getPcDrillId,data.getId()).eq(PcDrillDisaster::getEventType,EventTypeEnum.MAIN_EVENT.getCode()));
            if(disaster!=null)
            {
                pcDrillVO.setTyphoonNo(disaster.getTyphoonNo());
            }
            return pcDrillVO;
        });
        return new PageResult<>(drillVos);
    }

    @Override
    public List<PcDrill> getList(PcDrillQueryDTO queryDTO) {
        LambdaQueryWrapper<PcDrill> wrapper=getWrapper(queryDTO);
        if(wrapper==null)
        {
            return Collections.emptyList();
        }
        return list(wrapper);
    }

    private Boolean hasPliotAuth(String drillId)
    {
        List<PcDrillUserRole> userRoles=pcDrillRoleUserMapper.selectList(Wrappers.lambdaQuery(PcDrillUserRole.class)
                .in(PcDrillUserRole::getPcDrillId,drillId)
                .eq(PcDrillUserRole::getUserId,AuthUtil.getCurrentUserId()));
        //目前一个用户在一个演练只有一种角色
        if(CollectionUtils.isEmpty(userRoles))
        {
            return false;
        }
        if(SystemRoleConstant.TYPE_PILOT.equals(userRoles.get(0).getRoleName()))
        {
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startPcDrill(String drillId) {
        //校验是否有权限
        if(!hasPliotAuth(drillId))
        {
            throw new BizException("权限不足，无导调组角色");
        }
        PcDrill drill = getById(drillId);
        Assert.isFalse(ObjectUtil.isEmpty(drill), "演练查询为空");
        Assert.isFalse(StrUtil.equals(PcDrillConstant.STATUS_DOING, drill.getStatus()), "演练已启动，请刷新重试");
        List<PcDrillDutyUser> userList = pcDrillDutyUserMapper.selectList(
                Wrappers.lambdaQuery(PcDrillDutyUser.class)
                        .isNotNull(PcDrillDutyUser::getPrincipalIds)
                        .eq(PcDrillDutyUser::getPcDrillId, drillId)
        );
        Assert.notEmpty(userList,"参与人员不能为空，请先配置好组织架构与人员");

        if (DrillTypeEnum.EMERGENCY_COMMAND.getCode().equals(drill.getDrillType())){
            //应急指挥
            PcSchedulingEvent pcSchedulingEvent = schedulingEventManager.selectOne(
                    Wrappers.lambdaQuery(PcSchedulingEvent.class)
                            .eq(PcSchedulingEvent::getDrillId, drillId)
                            .last("limit 1")
            );
            Assert.notNull(pcSchedulingEvent,"应急指挥事件不存在");
//            pcDrillDisasterEventService.saveNewEvent(pcSchedulingEvent,drill);
        }else {
            //预案演练需要配事件
            Assert.notEmpty(pcDrillDisasterEventMapper.selectList(Wrappers.<PcDrillDisasterEvent>lambdaQuery()
                    .eq(PcDrillDisasterEvent::getPcDrillId, drillId)),"请先配置好演练方案再启动");
        }

        drill.setStatus(PcDrillConstant.STATUS_DOING);
        drill.setStartTime(LocalDateTime.now());

        PcDrillDisaster mainDisaster = pcDrillDisasterService.getOne(
                Wrappers.lambdaQuery(PcDrillDisaster.class)
                        .isNotNull(PcDrillDisaster::getPcPlanId)
                        .eq(PcDrillDisaster::getPcDrillId, drillId)
                        .eq(PcDrillDisaster::getEventType, EventTypeEnum.MAIN_EVENT.getCode())
                        .last("limit 1")
        );
        if (ObjectUtil.isNotNull(mainDisaster)){
            drill.setPcPlanId(mainDisaster.getPcPlanId());
        }else {
            drill.setPcPlanId(null);
        }
        updateById(drill);



        //新角色逻辑，SystemUserRole里面存的是主角色，而不是存演练角色
//        for (SystemUserRole needSaveUserRole : getDrillUserRoles(drillId)) {
//            LambdaQueryWrapper<SystemUserRole> wrapper = new LambdaQueryWrapper<>();
//            wrapper.eq(SystemUserRole::getRoleId,needSaveUserRole.getRoleId());
//            wrapper.eq(SystemUserRole::getUserId,needSaveUserRole.getUserId());
//            if(systemUserRoleMapper.selectCount(wrapper)<=0){
//                systemUserRoleMapper.insert(needSaveUserRole);
//            }
//        }
        if(drill.getDrillType().equals(DrillTypeEnum.EMERGENCY_COMMAND.getCode()))
        {
            schedulingEventManager.update(null,
                    Wrappers.lambdaUpdate(PcSchedulingEvent.class)
                            .eq(PcSchedulingEvent::getDrillId,drill.getId())
                            .set(PcSchedulingEvent::getStatus, EventStatusEnum.STARTED.getCode())
            );
        }


    }
    public Set<SystemUserRole> getDrillUserRoles(String drillId){
        List<PcDrillDutyUser> userList = pcDrillDutyUserMapper.selectList(
                Wrappers.lambdaQuery(PcDrillDutyUser.class)
                        .isNotNull(PcDrillDutyUser::getPrincipalIds)
                        .eq(PcDrillDutyUser::getPcDrillId, drillId)
        );
        List<PcDrillDutyOrg> dutyOrgList = pcDrillDutyOrgMapper.selectList(
                Wrappers.lambdaQuery(PcDrillDutyOrg.class)
                        .isNotNull(PcDrillDutyOrg::getRoleIds)
                        .eq(PcDrillDutyOrg::getPcDrillId,drillId)
        );
        Set<SystemUserRole> drillUserRoles = CollUtil.set(false);
        for (PcDrillDutyUser pcDrillDutyUser : userList) {
            List<String> principalIdList = StrUtil.split(pcDrillDutyUser.getPrincipalIds(), ",");
            for (String principalId : principalIdList) {
                Set<SystemUserRole> userRoles = getUserRoles(dutyOrgList, pcDrillDutyUser.getPcDrillOrgId(), principalId);
                if (CollUtil.isNotEmpty(userRoles)){
                    drillUserRoles.addAll(userRoles);
                }
            }

        }
        return drillUserRoles;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void endPcDrill(String drillId) {
        PcDrill drill = this.getById(drillId);
        cn.hutool.core.lang.Assert.isFalse(ObjectUtil.isEmpty(drill), "演练对象查询为空");
        cn.hutool.core.lang.Assert.isTrue(StrUtil.equals(PcDrillConstant.STATUS_DOING, drill.getStatus()), "演练不处于执行中状态，请刷新页面缓存重新操作");
        drill.setStatus(PcDrillConstant.STATUS_COMPLETE);
        drill.setEndTime(LocalDateTime.now());
        baseMapper.updateById(drill);
        //推送事件
        PushThread.pushDrill(drill);
    }

    @Override
    public String checkBeforeEndPcDrill(String drillId) {
        String msg="ok";

        List<PcDrillPlanDetail> planDetails=pcDrillPlanDetailService.list(Wrappers.lambdaQuery(PcDrillPlanDetail.class)
                .eq(PcDrillPlanDetail::getPcDrillId,drillId));
        //没有提交工作方案
        if(CollectionUtils.isEmpty(planDetails))
        {
            return msg;
        }
        //提交工作方案
        List<PcDrillPlanDetail> passDetails=planDetails.stream().filter(d->d.getStatus().equals(CheckStatusEnum.PASS.getCode())).collect(Collectors.toList());
        //有审批通过
        if(!CollectionUtils.isEmpty(passDetails))
        {

            for(PcDrillPlanDetail detail:passDetails)
            {
                List<PcDrillPlanTask> tasks=pcDrillPlanTaskService.list(Wrappers.lambdaQuery(PcDrillPlanTask.class)
                        .eq(PcDrillPlanTask::getPcDrillId,drillId).eq(PcDrillPlanTask::getPcDrillPlanDetailId,detail.getId()));
                //还没有执行
                if(CollectionUtils.isEmpty(tasks))
                {
                    return "该演练有未执行的任务，是否继续结束演练？";
                }
                List<PcDrillPlanTask> notPassTask=tasks.stream().filter(d->d.getStatus().equals(CheckStatusEnum.WAIT_APPROVAL.getCode()) || d.getStatus().equals(CheckStatusEnum.REJECT.getCode())).collect(Collectors.toList());
                //已执行，没有审批通过
                if(!CollectionUtils.isEmpty(notPassTask))
                {
                    return "该演练有已执行未审批通过的任务，是否继续结束演练？";
                }
            }


        }
        return msg;
    }


    private Set<SystemUserRole> getUserRoles(List<PcDrillDutyOrg> dutyOrgList, String parentOrgId, String userId){
        Set<SystemUserRole> needSaveUserRoles = CollUtil.set(false);
        Optional<PcDrillDutyOrg> dutyOrgOptional = dutyOrgList.stream()
                .filter(dutyOrg -> dutyOrg.getId().equals(parentOrgId)).findFirst();
        if (dutyOrgOptional.isPresent()){
            List<String> roleIds = StrUtil.split(dutyOrgOptional.get().getRoleIds(), ",");
            for (String roleId : roleIds) {
                SystemUserRole userRole = new SystemUserRole();
                userRole.setRoleId(roleId);
                userRole.setUserId(userId);
                userRole.setRoleType(RoleTypeEnum.DRILL.getCode());
                needSaveUserRoles.add(userRole);
            }
            //如果用户角色为空，则获取并继承上上一级的权限
            if (CollUtil.isEmpty(roleIds)){
                //不是第一级
                if (!StatusEnum.FALSE.getCode().equals(dutyOrgOptional.get().getAncestors())){
                    String lastParentOrgId = dutyOrgOptional.get().getParentId();
                    Set<SystemUserRole> userRoles = getUserRoles(dutyOrgList, lastParentOrgId, userId);
                    if (CollUtil.isNotEmpty(userRoles)){
                        needSaveUserRoles.addAll(userRoles);
                    }
                }
            }
        }
        return needSaveUserRoles;
    }

    @Override
    public PageResult<PcDrill> getHistoryDrill(PageParam<PcDrillQueryDTO> pageParam,String userId, String status) {
        IPage<PcDrill> iPage = pageParam.buildPage();
        IPage<PcDrill> page = baseMapper.getHistoryDrill(iPage,userId,status);
        return  new PageResult<>(page);
    }


    /**
     * 克隆演练
     * @param drillId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String clonePcDrill(String drillId) {
        //保存新的演练
        PcDrill pcDrill = baseMapper.selectById(drillId);
        pcDrill.setId(null)
                .setCreateBy(null)
                .setUpdateBy(null)
                .setCreateTime(null)
                .setUpdateTime(null);
        pcDrill.setStatus(PcDrillConstant.STATUS_PREPARE);
        String newName = pcDrill.getName()+" 副本";

        Long count = baseMapper.selectCount(Wrappers.<PcDrill>lambdaQuery().likeRight(PcDrill::getName, newName));
        pcDrill.setName(newName + (count+1));
        baseMapper.insert(pcDrill);
        //复制演练的附件
        List<SystemFileBusiness> list = systemFileBusinessService.list(
                Wrappers.<SystemFileBusiness>lambdaQuery()
                        .eq(SystemFileBusiness::getRelatedId, drillId)
                        .eq(SystemFileBusiness::getType, SystemFileBusinessConstant.TYPE_PC_DRILL)
        );
        for (SystemFileBusiness systemFileBusiness : list) {
            systemFileBusiness.setId(null)
                    .setCreateBy(null)
                    .setUpdateBy(null)
                    .setCreateTime(null)
                    .setUpdateTime(null);
            systemFileBusiness.setRelatedId(pcDrill.getId());
        }
        systemFileBusinessService.saveBatch(list);

        //克隆消息配置
        pcDrillDisasterService.cloneEvent(drillId,pcDrill.getId());

        //获取演练组织架构
        List<PcDrillDutyOrgVO> drillDutyOrg = pcDrillDutyOrgService.getDrillDutyOrg(drillId, pcDrill.getPcPlanId(),null);
        //拷贝组织架构
        if (CollUtil.isNotEmpty(drillDutyOrg)) {
            pcDrillDutyOrgService.saveDrillDutyOrg(drillDutyOrg,pcDrill.getId(),null,null);
        }
        return pcDrill.getId();
    }


    @Override
    public DrillStatisticsVO drillStatistics(String drillId) {
        return null;
    }

    @Override
    public String checkDrillExistUsers(Set<String> userIds) {
        List<String> status=Arrays.asList(PcDrillConstant.STATUS_PREPARE,PcDrillConstant.STATUS_DOING);
        List<PcDrill> drills=this.list(Wrappers.lambdaUpdate(PcDrill.class)
                .in(PcDrill::getStatus,status)
        );
        if(CollectionUtils.isEmpty(drills))
        {
            return null;
        }
//        List<PcDrill> doingDrills=drills.stream().filter(d->PcDrillConstant.STATUS_DOING.equals(d.getStatus())).collect(Collectors.toList());
        List<SystemUser> users=systemUserService.listByIds(userIds);
        Map<String, SystemUser> systemUserMap = IterUtil.toMap(users, SystemUser::getId);
        List<String> drillIds=drills.stream().map(PcDrill::getId).collect(Collectors.toList());
        List<PcDrillDutyUser> drillUsers=pcDrillDutyUserMapper.selectList(Wrappers.lambdaUpdate(PcDrillDutyUser.class)
                .in(PcDrillDutyUser::getPcDrillId,drillIds)
        );
        if(CollectionUtils.isEmpty(drillUsers))
        {
            return null;
        }
        //校验结果集合
        List<String> resultMsg=new ArrayList<>();
        userIds.stream().forEach(userId->{
            //不合格的演练id集合
            List<String> errorDrillIds=drillUsers.stream().filter(du->du.getPrincipalIds().contains(userId)).map(PcDrillDutyUser::getPcDrillId).distinct().collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(errorDrillIds))
            {
                List<String> errorDrillNames=drills.stream().filter(d->errorDrillIds.contains(d.getId())).map(PcDrill::getName).collect(Collectors.toList());
                SystemUser user=systemUserMap.get(userId);
                String msg="用户【"+user.getRealName()+"】"+"在这些演练中【"+String.join(",",errorDrillNames)+"】已被设置，请先移除用户或停止演练";
                resultMsg.add(msg);
            }

        });
        if(!CollectionUtils.isEmpty(resultMsg))
        {
            return String.join(";",resultMsg);
        }
        return null;
    }

    @Override
    public void deleteDrill(Set<String> ids) {

        ids.forEach(id-> {
            pcDrillDutyOrgService.remove(Wrappers.lambdaQuery(PcDrillDutyOrg.class).eq(PcDrillDutyOrg::getPcDrillId,id));
            pcDrillDutyUserMapper.delete(Wrappers.lambdaQuery(PcDrillDutyUser.class).eq(PcDrillDutyUser::getPcDrillId,id));
            pcDrillDisasterService.remove(Wrappers.lambdaQuery(PcDrillDisaster.class).eq(PcDrillDisaster::getPcDrillId,id));
            pcDrillDisasterEventService.remove(Wrappers.lambdaQuery(PcDrillDisasterEvent.class).eq(PcDrillDisasterEvent::getPcDrillId,id));
        });
        this.removeBatchByIds(ids);
    }

    private LambdaQueryWrapper<PcDrill> getWrapper(PcDrillQueryDTO queryDTO) {

        List<String> drillIds=null;
        //如果是超管，返回全部，如果不是超管，则判断演练是否包含用户，包含才返回
        if(!systemUserRoleService.isSuperAdmin())
        {
            LambdaQueryWrapper<PcDrillUserRole> pWrapper = Wrappers.lambdaQuery(PcDrillUserRole.class)
                    .eq(PcDrillUserRole::getUserId,AuthUtil.getCurrentUserId());
            drillIds=pcDrillRoleUserMapper.selectList(pWrapper).stream().map(PcDrillUserRole::getPcDrillId).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(drillIds))
            {
                return null;
            }
        }
        LambdaQueryWrapper<PcDrill> wrapper = Wrappers.lambdaQuery(PcDrill.class).last("order by create_time desc");
        wrapper.in(!CollectionUtils.isEmpty(drillIds),PcDrill::getId,drillIds);
        if (ObjectUtil.isNotEmpty(queryDTO)) {
            wrapper.like(ObjectUtil.isNotEmpty(queryDTO.getName()), PcDrill::getName, queryDTO.getName())
                    .like(ObjectUtil.isNotEmpty(queryDTO.getContent()), PcDrill::getContent, queryDTO.getContent())
                    .like(ObjectUtil.isNotEmpty(queryDTO.getAddress()), PcDrill::getAddress, queryDTO.getAddress())
                    .eq(ObjectUtil.isNotEmpty(queryDTO.getDrillType()),PcDrill::getDrillType,queryDTO.getDrillType())
                    .in(!CollectionUtils.isEmpty(queryDTO.getStatus()),PcDrill::getStatus,queryDTO.getStatus())
                    .ne(StatusEnum.TRUE.getCode().equals(queryDTO.getHideFinish()),PcDrill::getStatus,PcDrillConstant.STATUS_COMPLETE);
        }
        return wrapper;
    }

}
